package com.tagtraum.perf.gcviewer;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import javax.swing.BorderFactory;
import javax.swing.BoundedRangeModel;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicInternalFrameUI;
import javax.xml.ws.soap.Addressing;

import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import com.java.diagnostics.visualizer.displayer.html.HTMLReportDisplayer;
import com.java.diagnostics.visualizer.displayer.plot.ZoomingPlotDataDisplayer;
import com.java.diagnostics.visualizer.exceptions.GCAndMemoryVisualizerParsedDataCorruptedException;
import com.java.diagnostics.visualizer.impl.marshalling.Marshaller;
import com.java.diagnostics.visualizer.impl.marshalling.MarshallerImpl;
import com.java.diagnostics.visualizer.impl.sources.implementations.FileSourceImpl;
import com.java.diagnostics.visualizer.impl.sources.implementations.ZipFileSourceImpl;
import com.java.diagnostics.visualizer.parsers.Parser;
import com.java.diagnostics.visualizer.properties.OutputProperties;
import com.java.diagnostics.visualizer.sources.Source;
import com.tagtraum.perf.gcviewer.imp.DataReaderException;

/**
 * @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
 *         Date: May 5, 2005
 *         Time: 10:25:16 AM
 */
public class GCDocument extends JInternalFrame {

    private List<ChartPanelView> chartPanelViews = new ArrayList<ChartPanelView>();
    private ModelChart modelChartListFacade;
    private boolean showModelPanel = true;
    private boolean watched;
    private RefreshWatchDog refreshWatchDog;
    private GCPreferences preferences;
    private JPanel reportingWindow;
   

    //added by wenguang.huang 
    Marshaller marshaller;
	//added end by wenguang.huang 


	public GCDocument(final GCViewerGui gcViewer, String s) {
        super(s, true, true, true, false);
        this.refreshWatchDog = new RefreshWatchDog();
        refreshWatchDog.setGcDocument(this);
        preferences = gcViewer.getPreferences();
        //added by wenguang.huang 
        BasicInternalFrameUI   ui   =   (BasicInternalFrameUI)this.getUI();   
        ui.setNorthPane(null);
       
		//added end by wenguang.huang 
        showModelPanel = preferences.isShowDataPanel();
       
        modelChartListFacade = new MultiModelChartFacade();
        CardLayout layout = new CardLayout();
        reportingWindow = new JPanel(layout);
        addComponentListener(new ResizeListener());
        //GridBagLayout layout = new GridBagLayout();
        getContentPane().setLayout(new BorderLayout(0, 0));
        //added by wenguang.huang 
        marshaller = new MarshallerImpl();
		//added end by wenguang.huang 


        //getContentPane().setLayout(layout); // deleted by wenguang.huang 
        // TODO refactor; looks very similar to DesktopPane implementation
        getContentPane().setDropTarget(new DropTarget(this, DnDConstants.ACTION_COPY, new DropTargetListener(){
            public void dragEnter(DropTargetDragEvent e) {
                if (e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                    e.acceptDrag(DnDConstants.ACTION_COPY);
                } else {
                    e.rejectDrag();
                }
            }

            public void dragOver(DropTargetDragEvent dtde) {
            }

            public void dropActionChanged(DropTargetDragEvent dtde) {
            }

            public void dragExit(DropTargetEvent dte) {
            }

            public void drop(DropTargetDropEvent e) {
                try {
                    Transferable tr = e.getTransferable();
                    if (e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                        e.acceptDrop(DnDConstants.ACTION_COPY);
                        List<Object> list = (List<Object>)tr.getTransferData(DataFlavor.javaFileListFlavor);
                        File[] files = list.toArray(new File[list.size()]);
                        gcViewer.add(files);
                        GCDocument.this.getContentPane().invalidate();
                        e.dropComplete(true);
                    } else {
                        e.rejectDrop();
                    }
                } catch (IOException ioe) {
                    e.rejectDrop();
                    ioe.printStackTrace();
                } catch (UnsupportedFlavorException ufe) {
                    e.rejectDrop();
                    ufe.printStackTrace();
                }
            }
        }));

    }

    public RefreshWatchDog getRefreshWatchDog() {
        return refreshWatchDog;
    }

    public boolean isShowModelPanel() {
        return showModelPanel;
    }

    public void setShowModelPanel(boolean showModelPanel) {
        boolean mustRelayout = this.showModelPanel != showModelPanel;
        this.showModelPanel = showModelPanel;
        if (mustRelayout) {
            relayout();
        }
    }
   
    public JPanel getReportingWindow() {
 		return reportingWindow;
 	}

 	public void setReportingWindow(JPanel reportingWindow) {
 		this.reportingWindow = reportingWindow;
 	}
    /**
     * @return true, if any of the files has been reloaded
     * @throws DataReaderException if something went wrong reading the data
     */
    public boolean reloadModels(boolean background) throws DataReaderException {
        boolean reloaded = false;
        for (ChartPanelView chartPanelView : chartPanelViews) {
            reloaded |= chartPanelView.reloadModel(!refreshWatchDog.isRunning());
        }
        if (!background) {
            relayout();
        }
        return reloaded;
    }

    public ModelChart getModelChart() {
        return modelChartListFacade;
    }

    public GCPreferences getPreferences() {
        return preferences;
    }
    
    public void add(final URL url) throws DataReaderException{
    	//added by wenguang.huang 
    	
    if (((MarshallerImpl)marshaller).getParsers()== null) {
       ((MarshallerImpl)marshaller).initialiseParsers();
     }
    	
       
        Parser[] parsers =((MarshallerImpl)marshaller).getParsers() ;
  	    
	    boolean setReturnCode = false;

	      File file = new File(url.getFile());
	      Source source = null;
	      try
	      {
	        new ZipFile(file);
	        source = new ZipFileSourceImpl(file);
	      }
	      catch (ZipException localZipException) {
	        source = new FileSourceImpl(file);
	      }
	      catch (IOException e) {
	        e.printStackTrace();
	      }
	      boolean parsed =false;
	      for(int i=0;i<parsers.length;i++)
	      {
			try {
				parsed = ((MarshallerImpl)marshaller).isParseableSource(source, parsers[i]);
			} catch (GCAndMemoryVisualizerParsedDataCorruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (parsed)
			{
				break;
			}
	      }
	      
	    if(parsed)
	    {
	      try {
			    marshaller.addSource(source);
		    
		      } catch (GCAndMemoryVisualizerParsedDataCorruptedException e) 
		      {
			   
			   e.printStackTrace();
		      }
	    }
		//added end by wenguang.huang 
	  
	    ChartPanelView chartPanelView = new ChartPanelView(this, url);
        chartPanelViews.add(chartPanelView);
        chartPanelView.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if (ChartPanelView.EVENT_MINIMIZED.equals(event.getPropertyName())) {
                    relayout();
                }
            }
        });
        // make sure all models in one document have the same display properties
        if (chartPanelViews.size() > 1) {
            modelChartListFacade.setScaleFactor(modelChartListFacade.getScaleFactor());
            modelChartListFacade.setShowFullGCLines(modelChartListFacade.isShowFullGCLines());
            modelChartListFacade.setShowGCTimesLine(modelChartListFacade.isShowGCTimesLine());
            modelChartListFacade.setShowGCTimesRectangles(modelChartListFacade.isShowGCTimesRectangles());
            modelChartListFacade.setShowIncGCLines(modelChartListFacade.isShowIncGCLines());
            modelChartListFacade.setShowTotalMemoryLine(modelChartListFacade.isShowTotalMemoryLine());
            modelChartListFacade.setShowUsedMemoryLine(modelChartListFacade.isShowUsedMemoryLine());
        }
        
        relayout();
	  }
    

    public void removeChartPanelView(ChartPanelView chartPanelView) {
        chartPanelViews.remove(chartPanelView);
        relayout();
    }

    public void relayout() {
        getContentPane().removeAll();                
        if (chartPanelViews.size() > 1) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < chartPanelViews.size(); i++) {
                sb.append(chartPanelViews.get(i).getModel().getURL().getFile());
                if (i + 1 < chartPanelViews.size()) sb.append(", ");
            }
            setTitle(sb.toString());
        } else if (!chartPanelViews.isEmpty())
            setTitle(chartPanelViews.get(0).getModel().getURL().toString());
        else
            setTitle("");
        int row = 0;
        boolean noMaximizedChartPanelView = true;
        ChartPanelView lastMaximizedChartPanelView = getLastMaximizedChartPanelView();
        MasterViewPortChangeListener masterViewPortChangeListener = new MasterViewPortChangeListener();

        for (int i = 0; i < chartPanelViews.size(); i++) {
            final ChartPanelView chartPanelView = chartPanelViews.get(i);
            final ModelChartImpl modelChart = (ModelChartImpl) chartPanelView.getModelChart();
            final ModelPanel modelPanel = chartPanelView.getModelPanel();
            modelPanel.setBackground(Color.WHITE);
            final JTabbedPane modelChartAndDetails = chartPanelView.getModelChartAndDetails();

            modelPanel.setVisible(showModelPanel && (!chartPanelView.isMinimized()));
            
            //getContentPane().add(topPanel, "North");
            SectionsModel analyticSections = new SectionsModel();
            analyticSections.addSectionHeading("Analytics Summary");
            analyticSections.addAnalyticSection("summary", WarningSeverityLevel.ADVICE, true);
            reportingWindow.add(modelPanel.getSummaryTab(),"summary");
            //addAnalytics(analytics.getFlagReports());
            analyticSections.addSectionHeading("Memory");
            analyticSections.addAnalyticSection("memory details", WarningSeverityLevel.ADVICE, true);
            reportingWindow.add(modelPanel.getMemoryTab(),"memory details");
            //addAnalytics(analytics.getHeapUtilisationReports());
            analyticSections.addSectionHeading("PAUSE");
            analyticSections.addAnalyticSection("pause details", WarningSeverityLevel.ADVICE, true);
            reportingWindow.add(modelPanel.getPauseTab(),"pause details");
            //addAnalytics(analytics.getPauseTimeReports());
            //analyticSections.addSectionHeading("SYSTEM GC");
            
            SectionsModel dataSections = new SectionsModel();
            dataSections.addSectionHeading("Chart");
            
            //addAnalytics(analytics.getFlagReports());
            dataSections.addSection("chart details");
            if(chartPanelView.getDrawlines()!=null)
              reportingWindow.add(chartPanelView.getDrawlines(),"chart details");
            else
              reportingWindow.add(chartPanelView.getModelchartJPanel(),"chart details");
            dataSections.addSectionHeading("Event");
            dataSections.addSection("event details");
            reportingWindow.add(chartPanelView.getModelDetailsPanel(),"event details");
            //addAnalytics(analytics.getHeapUtilisationReports());
            dataSections.addSectionHeading("Report");
            //addAnalytics(analytics.getPauseTimeReports());
            dataSections.addSection("report details");
            
            
            JPanel baogao = new JPanel(); 
           
            OutputProperties props = marshaller.getOutputProps(null);
            HTMLReportDisplayer testDisplayer =new HTMLReportDisplayer();
            ZoomingPlotDataDisplayer testPlot = new ZoomingPlotDataDisplayer();
           
  	        FillLayout layout = new FillLayout();
  	        
  	        baogao.setLayout(new GridBagLayout());
  	   
  	        Object result =testDisplayer.display(((MarshallerImpl)marshaller).getDataSet(), props);

  	        testPlot.display(((MarshallerImpl)marshaller).getDataSet(), props);

  	        JEditorPane editorPane = new JEditorPane();
  	        
  	        
  	        editorPane.setEditable(false);    
  	        try {
  	    	File file = new File(result.toString());
  	    	String path = file.getAbsolutePath(); 
  	    	editorPane.setPage("file:///"+path);
  	    	
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			//added end by wenguang.huang 2014��4��17�� ����10:56:16


           // reportingWindow.add(new JScrollPane(chartPanelView.getBaogao()),"report details");
  	        reportingWindow.add(new JScrollPane(editorPane),"report details");
            dataSections.addSectionHeading("GC Content");
            dataSections.addSection("GC Content details");
            reportingWindow.add(chartPanelView.getJpanel_log(),"GC Content details");
            //reportingWindow.add(tempFrame,"GC Content details");
            SectionsModel feedbackSections = new SectionsModel();

            feedbackSections.addAnalyticSection("Feedback", WarningSeverityLevel.ADVICE, true);
            
            SidePanel sidePanel = new SidePanel(analyticSections, dataSections, feedbackSections);
            getContentPane().add(new JScrollPane(sidePanel,20,31),BorderLayout.WEST);
            

            SectionChangeBus.INSTANCE.subscribe(new SectionSwitcher(reportingWindow));
            getContentPane().add(reportingWindow,BorderLayout.CENTER);
            
            
            if (!chartPanelView.isMinimized()) {
                noMaximizedChartPanelView = false;
                final boolean isLastMaximizedChartPanelView = lastMaximizedChartPanelView == chartPanelView;
                // lock viewports with each other...
                // remove old master listeners
                final JViewport viewport = modelChart.getViewport();
                lockChartsToOneScrollbar(viewport, isLastMaximizedChartPanelView, modelChart, masterViewPortChangeListener);

                final JScrollBar horizontalScrollBar = modelChart.getHorizontalScrollBar();
                // clean old change listeners
                ChangeListener[] changeListeners = ((DefaultBoundedRangeModel) horizontalScrollBar.getModel()).getChangeListeners();
                for (int j = 0; j < changeListeners.length; j++) {
                    if (changeListeners[j] instanceof ScrollBarMaximumChangeListener) {
                        horizontalScrollBar.getModel().removeChangeListener(changeListeners[j]);
                    }
                }
                if (isLastMaximizedChartPanelView && isWatched()) {
                    horizontalScrollBar.getModel().addChangeListener(new ScrollBarMaximumChangeListener());
                }
                if (isLastMaximizedChartPanelView) {
                    horizontalScrollBar.setEnabled(!isWatched());
                }
            }
            row++;
        }
        if (noMaximizedChartPanelView) {
            
            GridBagConstraints constraints = new GridBagConstraints();
            constraints.fill = GridBagConstraints.BOTH;
            constraints.gridy = row;
            constraints.weightx = 3;
            constraints.weighty = 3;
            getContentPane().add(new JPanel(), constraints); 
           


        }
        //added by wenguang.huang 2014��2��21�� ����1:11:59
        this.setVisible(true);
		//added end by wenguang.huang 2014��2��21�� ����1:11:59


        scaleModelChart();
                
        invalidate();
    }

    private void lockChartsToOneScrollbar(final JViewport viewport, final boolean lastMaximizedChartPanelView, final ModelChartImpl modelChart, MasterViewPortChangeListener masterViewPortChangeListener) {
        ChangeListener[] changeListeners = viewport.getChangeListeners();
        for (int j = 0; j < changeListeners.length; j++) {
            if (changeListeners[j] instanceof MasterViewPortChangeListener) {
                viewport.removeChangeListener(changeListeners[j]);
            }
        }
        if (lastMaximizedChartPanelView) {
            modelChart.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
           
            viewport.addChangeListener(masterViewPortChangeListener);
        } else {
            modelChart.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            masterViewPortChangeListener.addSlaveViewport(viewport);
        }
    }

    public int getChartPanelViewCount() {
        return chartPanelViews.size();
    }

    public ChartPanelView getChartPanelView(int i) {
        return chartPanelViews.get(i);
    }

    public void setWatched(boolean watched) {
        this.watched = watched;
        final JScrollBar horizontalScrollBar = ((ModelChartImpl) getLastMaximizedChartPanelView().getModelChart()).getHorizontalScrollBar();
        if (watched) {
            horizontalScrollBar.setValue(horizontalScrollBar.getMaximum());
        }
        horizontalScrollBar.setEnabled(!watched);
    }

    public boolean isWatched() {
        return watched;
    }

    private static class MasterViewPortChangeListener implements ChangeListener {
        private List<JViewport> slaveViewPorts = new ArrayList<JViewport>();

        public void addSlaveViewport(JViewport viewPort) {
            slaveViewPorts.add(viewPort);
        }

        public void stateChanged(ChangeEvent e) {
            JViewport master = (JViewport) e.getSource();
            final int x = master.getViewPosition().x;
            for (JViewport slave : slaveViewPorts) {
                slave.setViewPosition(new Point(x, slave.getViewPosition().y));
            }
        }
    }

    public ChartPanelView getLastMaximizedChartPanelView() {
        ChartPanelView lastMaximizedChartPanelView = null;
        for (int i = 0; i < chartPanelViews.size(); i++) {
            final ChartPanelView chartPanelView = chartPanelViews.get(i);
            if (!chartPanelView.isMinimized()) lastMaximizedChartPanelView = chartPanelView;
        }
        return lastMaximizedChartPanelView;
    }

    private void scaleModelChart() {
        for (int i = 0; i < chartPanelViews.size(); i++) {
            final ChartPanelView aChartPanelView = (chartPanelViews.get(i));
            aChartPanelView.getModelChart().setFootprint(getMaxFootprint());
            aChartPanelView.getModelChart().setMaxPause(getMaxMaxPause());
            aChartPanelView.getModelChart().setRunningTime(getMaxRunningTime());
        }
    }

    private double getMaxRunningTime() {
        double max = 0;
        for (int i = 0; i < chartPanelViews.size(); i++) {
            max = Math.max(max, chartPanelViews.get(i).getModel().getRunningTime());
        }
        return max;
    }

    private long getMaxFootprint() {
        long max = 0;
        for (int i = 0; i < chartPanelViews.size(); i++) {
            max = Math.max(max, chartPanelViews.get(i).getModel().getFootprint());
        }
        return max;
    }

    private double getMaxMaxPause() {
        double max = 0;
        for (int i = 0; i < chartPanelViews.size(); i++) {
            max = Math.max(max, chartPanelViews.get(i).getModel().getPause().getMax());
        }
        return max;
    }


    private class MultiModelChartFacade implements ModelChart {

        @Override
        public boolean isAntiAlias() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isAntiAlias();
        }

        @Override
        public void setAntiAlias(boolean antiAlias) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setAntiAlias(antiAlias);
            }
        }

        @Override
        public long getFootprint() {
            if (chartPanelViews.isEmpty()) return 0;
            return chartPanelViews.get(0).getModelChart().getFootprint();
        }

        @Override
        public double getMaxPause() {
            if (chartPanelViews.isEmpty()) return 0;
            return chartPanelViews.get(0).getModelChart().getMaxPause();
        }

        @Override
        public void setRunningTime(double runningTime) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setRunningTime(runningTime);
            }
        }

        @Override
        public void setFootprint(long footPrint) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setFootprint(footPrint);
            }
        }

        @Override
        public void setMaxPause(double maxPause) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setMaxPause(maxPause);
            }
        }

        @Override
        public void setScaleFactor(double scaleFactor) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setScaleFactor(scaleFactor);
            }
        }

        @Override
        public double getScaleFactor() {
            if (chartPanelViews.isEmpty()) return 1;
            return chartPanelViews.get(0).getModelChart().getScaleFactor();
        }

        @Override
        public boolean isShowGCTimesLine() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowGCTimesLine();
        }

        @Override
        public void setShowGCTimesLine(boolean showGCTimesLine) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowGCTimesLine(showGCTimesLine);
            }
        }

        @Override
        public boolean isShowGCTimesRectangles() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowGCTimesRectangles();
        }

        @Override
        public void setShowGCTimesRectangles(boolean showGCTimesRectangles) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowGCTimesRectangles(showGCTimesRectangles);
            }
        }

        @Override
        public boolean isShowFullGCLines() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowFullGCLines();
        }

        @Override
        public void setShowFullGCLines(boolean showFullGCLines) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowFullGCLines(showFullGCLines);
            }
        }

        @Override
        public boolean isShowIncGCLines() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowIncGCLines();
        }

        @Override
        public void setShowIncGCLines(boolean showIncGCLines) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowIncGCLines(showIncGCLines);
            }
        }

        @Override
        public boolean isShowTotalMemoryLine() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowTotalMemoryLine();
        }

        @Override
        public void setShowTotalMemoryLine(boolean showTotalMemoryLine) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowTotalMemoryLine(showTotalMemoryLine);
            }
        }

        @Override
        public void setShowTenured(boolean showTenured) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowTenured(showTenured);
            }
        }

        @Override
        public boolean isShowTenured() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowTenured();
        }

        @Override
        public void setShowYoung(boolean showYoung) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowYoung(showYoung);
            }
        }

        @Override
        public boolean isShowYoung() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowYoung();
        }

        @Override
        public boolean isShowUsedMemoryLine() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowUsedMemoryLine();
        }

        @Override
        public void setShowUsedMemoryLine(boolean showUsedMemoryLine) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowUsedMemoryLine(showUsedMemoryLine);
            }
        }

        @Override
        public boolean isShowUsedTenuredMemoryLine() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowUsedTenuredMemoryLine();
        }

        @Override
        public void setShowUsedTenuredMemoryLine(boolean showUsedTenuredMemoryLine) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowUsedTenuredMemoryLine(showUsedTenuredMemoryLine);
            }
        }

        @Override
        public boolean isShowUsedYoungMemoryLine() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowUsedYoungMemoryLine();
        }

        @Override
        public void setShowUsedYoungMemoryLine(boolean showUsedYoungMemoryLine) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowUsedYoungMemoryLine(showUsedYoungMemoryLine);
            }
        }

        @Override
        public void setShowInitialMarkLevel(boolean showInitialMarkLevel) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowInitialMarkLevel(showInitialMarkLevel);
            }
        }

        @Override
        public boolean isShowInitialMarkLevel() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowInitialMarkLevel();
        }

        @Override
        public void setShowConcurrentCollectionBeginEnd(boolean showConcurrentCollectionBeginEnd) {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().setShowConcurrentCollectionBeginEnd(showConcurrentCollectionBeginEnd);
            }
        }

        @Override
        public boolean isShowConcurrentCollectionBeginEnd() {
            if (chartPanelViews.isEmpty()) return false;
            return chartPanelViews.get(0).getModelChart().isShowConcurrentCollectionBeginEnd();
        }

        @Override
        public void resetPolygonCache() {
            for (ChartPanelView chartPanelView : chartPanelViews) {
                chartPanelView.getModelChart().resetPolygonCache();
            }
        }

    }

    private class ScrollBarMaximumChangeListener implements ChangeListener {

        public void stateChanged(ChangeEvent e) {
            if (isWatched()) {
                BoundedRangeModel model = (BoundedRangeModel) e.getSource();
                model.setValue(model.getMaximum());
            }
        }

    }
    
    /**
     * 
     * 
     * @author <a href="mailto:gcviewer@gmx.ch">Joerg Wuethrich</a>
     * <p>created on: 22.07.2012</p>
     */
    private class ResizeListener extends ComponentAdapter {

        @Override
        public void componentResized(ComponentEvent e) {
            modelChartListFacade.resetPolygonCache();
        }
        
    }
}
